<template>
  <div class="blue-tooth">
    <div class="blue-tooth__mask"></div>
    <Dialog v-model="isShowOpen" theme="round-button" title="提示" :overlay="false" @confirm="openBlueTooth">
      <p>请打开手机蓝牙，然后连接对应仪器蓝牙</p>
    </Dialog>

    <Dialog v-model="showBlueToothList" theme="round-button" show-cancel-button title="连接蓝牙" :beforeClose="beforeClose"
      :confirmButtonText="confirmButtonText">
      <van-list v-model="isScan" :finished="finished" loading-text=" " class="blue-tooth__list">
        <van-cell v-for="(item, index) in columns" :key="index" @click="connect(item)" size="large">
          <template #title>
            <div style="font-size:16px">{{ item.name + ' - ' + item.id }}</div>
          </template>
          <template #right-icon>
            <img class="blue-tooth__signal-icon" :src="signalLevel.find(i => item.rssi <= i.value)?.icon" />
          </template>
        </van-cell>
      </van-list>
    </Dialog>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import Dialog from '@/components/dialog';
import level1 from '@/assets/signal-level-1.svg';
import level2 from '@/assets/signal-level-2.svg';
import level3 from '@/assets/signal-level-3.svg';
import level4 from '@/assets/signal-level-4.svg';
import { testerList } from '@/config/tester'
import { isEnabled, startStateNotifications, enable, startScanWithOptions, stopScan, autoConnect, requestMtu } from '@/modules/bluetooth'
import { storage } from '@/modules/storage';
import { log } from '@/utils';

@Component({
  name: 'BlueTooth',
  components: {
    Dialog,
  },
})
export default class BlueTooth extends Vue {
  // 是否打开蓝牙
  private isOpenBlueTooth = false;
  // 显示蓝牙列表
  private showBlueToothList = false;
  // 蓝牙列表
  private columns: BLECentralPlugin.PeripheralData[] = [];
  // 正在扫描蓝牙设备
  private isScan = false;
  // 扫描完成
  private finished = false;
  private serviceUUID = 'fff0';
  // 指定蓝牙开头关键字
  private get keywords() {
    const tester = testerList.find(item => item.key === this.$store.state.tester);
    return tester ? [`CSG-${tester.blueName}`, `CSC-${tester.blueName}`] : ['CSG', 'CSC'];
  }

  private signalLevel = [{
    value: -80,
    icon: level1
  }, {
    value: -70,
    icon: level2
  }, {
    value: -60,
    icon: level3
  }, {
    value: Infinity,
    icon: level4
  }];

  get isShowOpen() {
    return !this.isOpenBlueTooth;
  }

  set isShowOpen(value) {
    this.$emit('update:isShowOpen', value);
  }

  get confirmButtonText() {
     return this.isScan ? '停止扫描' : '开始扫描';
  }

  mounted() {
    this.init();
  }

  init() {
    // 进入判断是否开启蓝牙
    isEnabled().then(() => {
      this.isOpenBlueTooth = true;
      this.showBlueToothList = true;
      this.startScan();
      this.isScan = true;
    }).catch(() => {
      this.isOpenBlueTooth = false;
    })

    startStateNotifications().then((state) => {
      if (state === 'on') {
        this.isOpenBlueTooth = true;
        this.showBlueToothList = true;
        this.startScan();
        this.isScan = true;
      }
      if (state === 'off') {
        this.isOpenBlueTooth = false;
      }
    })
  }

  // 请求打开蓝牙
  openBlueTooth() {
    enable().then(() => {
      this.$toast.success({ message: '成功开启蓝牙', duration: 1000 });
      this.isOpenBlueTooth = true;
      this.showBlueToothList = true;
      this.isScan = true;
    }).catch(() => {
      this.$toast.fail({ message: '打开蓝牙失败', duration: 1000 });
    })
  }

  // 蓝牙扫描设备
  startScan() {
    this.finished = false;
    this.columns = [];
    startScanWithOptions((device) => {
      // 过滤没有名称的蓝牙设备
      if (!device.name) return;
      // 过滤已经在列表里的蓝牙设备
      if (this.columns.some(item => item.id === device.id)) return;
      console.log('蓝牙扫描结果', device);
      // 过滤不包含关键字的蓝牙设备，若为空则不过滤
      if (!this.keywords.some(w => device.name.startsWith(w))) {
        return;
      }
      this.columns.push(device)
    })
  }

  // 蓝牙连接
  connect(item: BLECentralPlugin.PeripheralData) {
    this.$toast.loading({ message: '正在连接中', duration: 0, forbidClick: false, loadingType: 'spinner' });
    autoConnect(item.id).then(res => {
      this.$toast.clear();
      this.$toast.success({ message: '连接成功', duration: 1500 });
      storage.set('mac', res.id);
      this.setUUID(res.characteristics || [])
      // this.showBlueToothList = false;
      // this.isScan = false;

      return stopScan();
    }).then(() => {
      this.finished = true;
      //   return requestMtu(512)
      // }).then((MTU) => {
      //   log('设置MTU成功', MTU);
      this.$emit('connect');
    }).catch((err) => {
      this.$toast.clear();
      this.$toast({ message: `连接失败\n${err}`, duration: 1500 });
    })
  }

  // 设置特征码
  setUUID(charList: BLECentralPlugin.PeripheralCharacteristic[]) {
    let writeCharUUID = '';
    let notifyCharUUID = '';
    if (charList.length > 0) {
      const targetChar = charList.filter(x => x.service === this.serviceUUID);
      targetChar.forEach(x => {
        if (
          x.properties.indexOf("Write") !== -1 ||
          x.properties.indexOf("WriteWithoutResponse") !== -1
        ) {
          writeCharUUID = x.characteristic;
        }
        if (x.properties.indexOf("Notify") !== -1) {
          notifyCharUUID = x.characteristic;
        }
      });
    }
    storage.set('writeCharUUID', writeCharUUID);
    storage.set('notifyCharUUID', notifyCharUUID);
  }

  beforeClose(action: 'confirm' | 'cancel', done: (cb?: boolean) => void) {
    if (action === 'confirm') {
      this.isScan = !this.isScan;
      done(false);
      return;
    }
    if (action === 'cancel') {
      stopScan().then(() => {
        this.$router.back();
        done(false);
      })
    }
  }

  beforeDestroy() {
    this.isScan = false;
  }

  destroyed() {
    console.log('blue-tooth destroyed');
    stopScan();
  }

}
</script>

<style lang="scss" scoped>
.blue-tooth {
  background-color: rgba(255, 255, 255, 1);
  width: 100vw;
  height: 100vh;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 10;
  margin-top: 80px;

  &__mask {
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.4);
  }

  &__list {
    height: 200px;
    overflow-y: scroll;
  }

  &__signal-icon {
    width: 20px;
    height: 20px;
  }
}
</style>
